package com.gem.service.impl;

import com.gem.entity.Log;
import com.gem.entity.Room;
import com.gem.entity.User;
import com.gem.enums.ClientMessageType;
import com.gem.factory.log.LogFactory;
import com.gem.factory.room.RoomFactory;
import com.gem.netty.entity.Content;
import com.gem.netty.session.GroupSession;
import com.gem.netty.session.GroupSessionFactory;
import com.gem.pipeline.ProcessContext;
import com.gem.pipeline.ProcessController;
import com.gem.pipeline.ProcessModel;
import com.gem.service.RoomService;
import com.gem.factory.user.UserFactory;
import com.gem.service.UserService;
import com.gem.utils.Page;
import com.gem.utils.R;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Author: Xhy
 * CreateTime: 2022-09-17 23:41
 */
@Service
public class RoomServiceImpl implements RoomService {

    @Autowired
    private UserService userService;

    @Override
    public R list() {
        Map<String, Room> rooms = RoomFactory.listRooms();
        return R.ok().data("data",rooms.values());
    }




    private void nettyCreateRoom(Room room) {
        String userId = room.getRoomOwnerId();
        String roomId = room.getRoomId();
        GroupSession groupSession = GroupSessionFactory.getGroupSession();
        HashSet<String> set = new HashSet<>();
        set.add(userId);
        groupSession.createGroup(roomId,set);
    }

    private class RoomInfo implements ProcessModel {
        private String roomId;
        private String userId;

        private RoomInfo(String rId,String uId){
            this.roomId = rId;
            this.userId = uId;
        }
    }
    @Override

    public R joinRoom(String roomId, String userId) {

        // 是否存在该房间
        if (!RoomFactory.existRoom(roomId)){
            return R.error().message(roomId+":房间不存在");
        }

        // 是否重复加入
        if (RoomFactory.existRoomInUser(roomId,userId)){
            return R.error().message("你已存在该房间").code(201);
        }


        // 房间人数是否已满
        if (RoomFactory.existRoomFull(roomId)){
            return R.error().message("房间已满");
        }

        RoomFactory.join(roomId,userId);
        GroupSession groupSession = GroupSessionFactory.getGroupSession();
        groupSession.joinMember(roomId,userId);
        // 给房间发送消息
        List<Channel> members = groupSession.getMembersChannel(roomId);
        for (Channel member : members) {
            member.writeAndFlush( new TextWebSocketFrame(R.ok().message(UserFactory.get(userId) + "加入房间")
                    .type(ClientMessageType.JOIN_ROOM.type).toString()));
        }
        Log log = new Log();
        log.setMessage(UserFactory.get(userId) + "加入房间");
        log.setDate(new Date());
        LogFactory.add(roomId,log);
        return R.ok().message("已加入房间");
    }

    @Override
    public R quitRoom(String roomId, String userId) {
        if (!RoomFactory.existRoom(roomId)){
            return R.error().message("不存在该房间");
        }
        RoomFactory.quitRoom(roomId,userId);

        return R.ok().message("退出成功");
    }

    @Override
    public R search(String roomId) {


        return R.ok().data("data",RoomFactory.search(roomId));
    }

    @Override
    public R getRoomInUsers(String roomId) {
        // 校验房间是否存在
        if (!RoomFactory.existRoom(roomId)){
            return R.error().data("data","房间不存在");
        }

        return R.ok().data("data",RoomFactory.getRoomInMembers(roomId));
    }

    @Override
    public R createRoom(Room room) {
        String userId= room.getRoomOwnerId();
        String roomName = room.getRoomName();
        if (ObjectUtils.isEmpty(roomName)){
            return R.error().message("房间名称不可为空");
        }
        // 创建房间基本信息
        return RoomFactory.createRoom(roomName, userId);
    }

    @Override
    public R page(Integer curPage,Integer limit) {
        Map<String, Room> roomMap = RoomFactory.listRooms();
        List<Room> rooms = new ArrayList<>();
        roomMap.forEach((k,v)->{
            rooms.add(v);
        });
        Page<Room> roomPage = new Page<>();
        Page<Room> page = roomPage.page(rooms, curPage, limit);
        return R.ok().data("data",page.getSize() == 0 ? new Page<>() : page);
    }
}
